use axum::extract::{Path, Query};
use axum::{Router, Json};
use axum::routing::{get, post};
use redis::Commands;
use serde::{Serialize,Deserialize};
use tower_cookies::Cookies;

use crate::models::*;

use crate::utils::cookie;

type RouterResult<T> = Result<T,String>;

#[derive(Deserialize,Serialize)]
struct CommunicationResponse{
    pub discription:String,
    pub status:String,
    pub help_id:String,
    pub answer_id:String,
}

impl CommunicationResponse{
    pub fn ok(discription:String,help_id:String,answer_id:String) -> CommunicationResponse {
        CommunicationResponse { discription, status: "ok".to_string(), help_id,answer_id}
    }

    pub fn err(discription:String,help_id:String,answer_id:String) -> CommunicationResponse {
        CommunicationResponse { discription, status: "err".to_string(), help_id,answer_id}
    }

}

pub fn router() -> Router {
    Router::new()
        .route("/", get(index))
        .route("/make_help", post(make_help))
        .route("/delete_help", get(delete_help))
        .route("/update_help", post(update_help))
        .route("/make_answer", post(make_answer))
        .route("/update_answer", post(update_answer))
        .route("/delete_answer", get(delete_answer))
        .route("/request_list", get(get_request_list))
        .route("/recom_friends_list", get(get_recom_friends_list))
        .route("/add_friend", get(add_friends))
        .route("/request_add_friend",get(request_add_friend))
        .route("/delete_friend", get(delete_friend))
        .route("/recommend_to_friends",get(recommend_to_friend))
        .route("/get_user_image",get(get_current_user_image))
        .route("/get_all_friends",get(get_all_friends))
        .route("/get_all_help_by_current_user",get(get_all))


}
async fn index(cookies:Cookies) -> RouterResult<String> {
    let user_id = cookie::get_user_id_from_cookie(cookies).unwrap();

    let user_id: i32 = user_id.parse().unwrap();

    let user = User::fetch_one_by_id(user_id).await.map_err(|err| err.to_string())?;

    Ok(format!("欢迎来到commmunication 特权首页，{}！",user.nickname))

}

/// 获取当前用户写的所有求助贴
async fn get_all(cookies:Cookies) -> Json<Vec<Help>> {
    // let guides = Help::fe
    let author_id = cookie::get_user_id_from_cookie(cookies).unwrap();
    let author_id: i32 = author_id.parse().unwrap();
    let helps = Help::fetch_all_by_author_id(author_id).await.unwrap();

    Json(helps)

}


#[derive(Serialize,Deserialize)]
struct PartUser{
    pub id:i32,
    pub nickname: String,
    pub email: String,
    pub phone_number:String,
}

/// 获取当前用户头像图片的url
async fn get_current_user_image(cookies:Cookies) -> Json<String> {
    let user = cookie::get_user_from_cookies(cookies).await.unwrap();
    if let Ok(image_url) = user.get_user_image().await{
        Json(image_url)
    }else {
        Json("获取出错！".to_string())
    }
}


/// 获取好友请求列表
async fn get_request_list(cookies:Cookies) -> Json<Vec<AttachedUser>> {
    let user = cookie::get_user_from_cookies(cookies).await.unwrap();
    let res = user.get_request_list().await.unwrap();
    let mut users = vec![];
    // res.iter().map(|item|{
    //
    // })

    for user in res {
        let image = user.get_user_image().await.unwrap();
        let attach_user = AttachedUser{
            id: user.id,
            nickname: user.nickname,
            image
        };
        users.push(attach_user);
    }

    Json(users)
}

/// 获取好友推荐列表
async fn get_recom_friends_list(cookies:Cookies) -> Json<Vec<AttachedUser>> {
    let user = cookie::get_user_from_cookies(cookies).await.unwrap();
    let res = user.get_recom_friend().await.unwrap();

    let mut users = vec![];

    for user in res {
        let image = user.get_user_image().await.unwrap();
        let attach_user = AttachedUser{
            id: user.id,
            nickname: user.nickname,
            image
        };
        users.push(attach_user);
    }

    Json(users)
}


/// 获取所有好友
async fn get_all_friends(cookies:Cookies) -> Json<Vec<AttachedUser>> {
    let user = cookie::get_user_from_cookies(cookies).await.unwrap();
    let mut users = vec![];
    for user_id in user.friends{
        let u = User::fetch_one_by_id(user_id).await.unwrap();
        let image = u.get_user_image().await.unwrap();

        let au = AttachedUser{
            id:user_id,
            nickname: u.nickname,
            image
        };
        users.push(au);
    }
    Json(users)

}

#[derive(Serialize,Deserialize)]
struct AddFriend{
    pub user_id:i32
}
/// 请求添加好友（放到好友添加列表中）
async fn request_add_friend(Query(query): Query<AddFriend>,cookies:Cookies) -> Json<CommunicationResponse> {
    let user_id = cookie::get_user_id_from_cookie(cookies).unwrap();
    let user_id: i32 = user_id.parse().unwrap();
    let mut friend = User::fetch_one_by_id(query.user_id).await.unwrap();



    let res = friend.push_request(user_id).await;

    if let Err(err) = res {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }
    Json(CommunicationResponse::ok("请求添加好友成功！".to_string(), "".to_string(),"".to_string()))
}

/// 添加好友
async fn add_friends(Query(query): Query<AddFriend>,cookies:Cookies) -> Json<CommunicationResponse> {
    let mut user = cookie::get_user_from_cookies(cookies).await.unwrap();
    let res = user.add_friends(query.user_id).await;
    if let Err(err) = res {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }
    Json(CommunicationResponse::ok("添加好友成功！".to_string(), "".to_string(),"".to_string()))
}
#[derive(Serialize,Deserialize)]
struct DeleteFriend{
    pub user_id:i32
}

/// 删除好友
async fn delete_friend(Query(query): Query<AddFriend>,cookies:Cookies) -> Json<CommunicationResponse> {
    let mut user = cookie::get_user_from_cookies(cookies).await.unwrap();
    let res = user.delete_friend(query.user_id).await;
    if let Err(err) = res {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }
    Json(CommunicationResponse::ok("删除好友成功！".to_string(), "".to_string(),"".to_string()))

}

/// 发表求助贴

async fn make_help(Json(help):Json<CreateHelp>,cookies:Cookies) -> Json<CommunicationResponse> {
    let user = cookie::get_user_from_cookies(cookies).await;
    if let Err(err) = user {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }
    let user = user.unwrap();
    let help_id = Help::insert(user.id, help.theme, help.content, help.image, vec![], "cool".to_string()).await;

    if let Err(err) = help_id {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }

    let help_id = help_id.unwrap();
    
    Json(CommunicationResponse::ok("发表求助贴成功！".to_string(), help_id.to_string(),"".to_string()))
}

/// 更新求助贴
async fn update_help(Json(help):Json<UpdateHelp>,cookies:Cookies) -> Json<CommunicationResponse> {
    // let user = cookie::get_user_from_cookies(cookies).await;
    // if let Err(err) = user {
    //     return Json(CommunicationResponse::err(err.to_string(), "".to_string()));
    // }
    // let user = user.unwrap();
    // let help_id = Help::update_all_by_id(help.id, help.theme, help.content, image, answers, status)
    let res = Help::update_part_by_id(help.id, help.theme, help.content, help.image).await;

    if let Err(err) = res {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }

    // let help_id = help_id.unwrap();
    
    Json(CommunicationResponse::ok("更新求助贴成功！".to_string(), help.id.to_string(),"".to_string()))
}


#[derive(Deserialize,Serialize)]
struct DeleteHelp {
    help_id:i32
}

/// 删除求助贴
async fn delete_help(Query(delete_help): Query<DeleteHelp>,cookies:Cookies) -> Json<CommunicationResponse> {

    let user_id = cookie::get_user_id_from_cookie(cookies);

    if user_id.is_none() {
        return Json(CommunicationResponse::err("虽然不知道为啥你能进来，你没有登录！".to_string(), "".to_string(),"".to_string()));
    }
    let user_id:i32 = user_id.unwrap().parse().unwrap();

    let help = Help::fetch_one_by_id(delete_help.help_id).await;
    if let Err(err) = help {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }

    let help = help.unwrap();
    if help.author_id != user_id {  //若求助贴作者不是user_id
        return Json(CommunicationResponse::err("你不是作者，删不了！".to_string(), "".to_string(),"".to_string()));
    } 

    let res = Help::delete_by_id(delete_help.help_id).await;

    if let Err(err) = res {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }

    return Json(CommunicationResponse::ok("删除求助贴成功！".to_string(), delete_help.help_id.to_string(),"".to_string()))

}

/// 发表答案

async fn make_answer(Json(answer): Json<CreateHelpAnswer>,cookies:Cookies) -> Json<CommunicationResponse> {

    //1. 获取当前用户id
    let user_id = cookie::get_user_id_from_cookie(cookies);

    if user_id.is_none(){
        return Json(CommunicationResponse::err("你没有登录，你咋进来的？".to_string(), "".to_string(),"".to_string()));
    }
    let user_id:i32 = user_id.unwrap().parse().unwrap();

    //2. 创建answer对象
    let anwser_id = HelpAnswer::insert(user_id, answer.help_id, answer.content, answer.image, "status".to_string()).await;

    if let Err(err) = anwser_id {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }
    let answer_id = anwser_id.unwrap();

    //3. 将answer对象加到 对应的Help对象中去
    let help = Help::fetch_one_by_id(answer.help_id).await;
    if let Err(err) = help {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }
    let mut help = help.unwrap();
    // if !help.answers.contains(&answer_id) {
    //     // Help::
    // }
    let res = help.push_answer(answer_id).await;
    if let Err(err) = res {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }

    Json(CommunicationResponse::ok("answer发表成功！".to_string(), answer.help_id.to_string(), answer_id.to_string()))

}

/// 更新答案
async fn update_answer(Json(answer):Json<UpdateHelpAnswer>,cookies:Cookies) -> Json<CommunicationResponse> {
    let user_id = cookie::get_user_id_from_cookie(cookies);
    if user_id.is_none(){
        return Json(CommunicationResponse::err("你没有登录，你咋进来的？".to_string(), "".to_string(),"".to_string()));
    }
    let user_id:i32 = user_id.unwrap().parse().unwrap();

    let res = HelpAnswer::update_part_by_id(answer.id, answer.content, answer.image).await;
    if let Err(err) = res {
        return Json(CommunicationResponse::err(err.to_string(), "".to_string(),"".to_string()));
    }

    Json(CommunicationResponse::ok("answer修改成功！".to_string(), answer.help_id.to_string(), answer.id.to_string()))
}

#[derive(Deserialize,Serialize)]
struct DeleteHelpAnswer {
    help_id:i32,
    answer_id: i32,
}


/// 删除答案
async fn delete_answer(Query(dh): Query<DeleteHelpAnswer>,cookies:Cookies) -> Json<CommunicationResponse> {
    let user_id = cookie::get_user_id_from_cookie(cookies);
    if user_id.is_none(){
        return Json(CommunicationResponse::err("你没有登录，你咋进来的？".to_string(), "".to_string(),"".to_string()));
    }
    let user_id:i32 = user_id.unwrap().parse().unwrap();

    let mut help = Help::fetch_one_by_id(dh.help_id).await.unwrap();
    let res = help.pop_answer(dh.answer_id).await.unwrap();

    _ = HelpAnswer::delete_by_id(dh.answer_id).await.unwrap();

    Json(CommunicationResponse::ok("answer删除成功！".to_string(), dh.help_id.to_string(), dh.answer_id.to_string()))

}

#[derive(Serialize,Deserialize)]
struct RecomUser{
    pub user_id:i32
}

/// 将User推荐给好友
async fn recommend_to_friend(Query(query): Query<RecomUser>,cookies:Cookies) -> Json<CommunicationResponse> {
    let user = cookie::get_user_from_cookies(cookies).await.unwrap();

    for friend_id in user.friends {
        if let Ok(friend) = User::fetch_one_by_id(friend_id).await{
            // friend.push
            if friend.id != query.user_id{
                let res = friend.push_recom_friend(query.user_id).await;
                if let Err(err) = res {
                    return Json(CommunicationResponse::err(err.to_string(), "".to_string(), "".to_string()));
                }
            }

        }
    }

    // Json()
    Json(CommunicationResponse::ok("请求发送成功！".to_string(), "".to_string(), "".to_string()))
}